#pragma once
#include "DAEFloat3.h"
/**
* This class describes a 3x3 matrix.
*/
class DAEMatrix33
{
public:
	/**
	* Create a new 3x3 matrix
	*/
	DAEMatrix33(void);

	/**
	* Creates a new matrix with the formula A * transpose A
	* @param A the float3 object to initialize the matrix with.
	*/
	DAEMatrix33(DAEFloat3 A);
	/**
	* Destroy the 3x3 matrix.
	*/
	virtual ~DAEMatrix33(void);
	/**
	* Transforms a vector with this matrix and stores the result
	* in vOut.
	* @param vOut the DAEFloat3 object to store the result in.
	* @param vToTransform the DAEFloat3 object to transform.
	*/
	void TransformVector(DAEFloat3& vOut, DAEFloat3& vToTransform) const;
	/**
	* Sets the value for a cell in the matrix.
	* @param row a number between 0 and 3 that indicates the row of
	* the cell.
	* @param column a number between 0 and 3 that indicates the column of
	* the cell.
	* @param value the value to set in the cell.
	*/
	void SetCell(int row, int column, float value);
	/**
	* Returns the value for a cell in the matrix.
	 @param row a number between 0 and 3 that indicates the row of
	* the cell.
	* @param column a number between 0 and 3 that indicates the column of
	* the cell.
	* @return the value of the cell
	*/
	float GetCell(int row, int column) const;
	/**
	* Fills an entire row with a given DAEFloat3 value.
	* @param row a number between 0 and 2 that indicates the row to fill.
	* @param value A DAEFloat3 object to fill the row with.
	*/ 
	void SetRow(int row, DAEFloat3& value);
	/**
	* Fills an entire row with the 3 float parameters.
	* @param row a number (0 to 2) that indicates the row to fill.
	* @param a1 the first value in the row.
	* @param a2 the second value in the row.
	* @param a3 the third value in the row.
	*/
	void SetRow(int row, float a1, float a2, float a3);
	/**
	* Fills an entire column with a given DAEFloat3 value.
	* @param column a number (0 to 2) that indicates the row to fill.
	* @param value a DAEFloat3 object to fill the column with.
	*/
	void SetColumn(int column, DAEFloat3& value);
	/**
	* Fills an entire column with the 4 float parameters.
	* @param column a number (0 to 3) that indicates the row to fill.
	* @param a1 the first value in the column.
	* @param a2 the second value in the column.
	* @param a3 the third value in the column.
	*/
	void SetColumn(int column, float a1, float a2, float a3);
	/**
	* Fills the data of one row into the provided DAEFloat4 object.
	* @param row the row to get.
	* @param value the DAEFloat4 object to fill.
	*/
	void GetRow(int row, DAEFloat3& value) const;
	/**
	* Fills the data of one column into the provided DAEFloat4 object.
	* @param column the column to get.
	* @param value the DAEFloat4 object to fill.
	*/
	void GetColumn(int column, DAEFloat3& value) const;
	/**
	* Replaces the values in this matrix with the identity matrix.
	*/
	void SetAsIdentity();
	/**
	* Calculates the inverse of this matrix and stores it into the result matrix.
	* @param result the result of the inverse operation.
	*/ 
	void Inverse(DAEMatrix33& result);
	/**
	* Returns the size of the value in bytes.
	* @return the size in bytes.
	*/
	int GetSizeInBytes() const{
		return 9*sizeof(float);
	}
	/**
	* Returns the pointer to the beginning of the value.
	* @return a void pointer to the beginning of the value.
	*/
	const void* GetValuePointer() const{
		return m_RMData;
	}

	/**
	* Calculates the determinant of this matrix.
	* @return the determinant of the matrix.
	*/
	float Determinant() const;
	
private:
	/**
	* The data for this matrix.
	*/
	float m_RMData[9];
};
